package day0328;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;

/**
 * 目标:
 * 1.在addClickAction()方法中，解决如下问题:
 *   1)将卡槽中相同的卡牌放到一起
 *   2)三连消
 */
public class Yang {
    public static void main(String[] args) {
        JFrame frame = new JFrame(); //创建一个窗口(相框)
        JPanel panel = new JPanel(); //创建一个面板(相板)
        //取消面板的默认布局(默认从左往右从上往下挨着排)，此时需要自己指定大小和位置
        panel.setLayout(null);

        paintBackground(panel); //画背景图

        ArrayList<JButton> cards = createCards(); //获取卡牌集合
        Collections.shuffle(cards); //洗牌(将cards集合中的元素乱序)

        /*
          发四层卡牌:
            第一层(最下面一层):7*7=49张
            第二层:6*6=36张
            第三层:5*7=35张
            第四层:4*6=24张
         */
        //发第一层(最下面一层)的49张卡牌
        putCards(cards,panel,49,0,7,30,100);
        //发第二层的36张卡牌
        putCards(cards,panel,36,49,6,60,130);
        //发第三层的35张卡牌
        putCards(cards,panel,35,49+36,7,30,160);
        //发第四层的24张卡牌
        putCards(cards,panel,24,49+36+35,6,60,190);

        allCover(cards); //压牌

        addClickAction(cards,panel); //为每张卡牌添加点击事件

        frame.add(panel); //将面板添加到窗口上
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //点窗口小叉子关闭时，停止整个程序
        frame.setSize(496,840); //设置窗口大小(比背景图大一些)
        frame.setLocationRelativeTo(null); //设置窗口相对于桌面做居中显示
        frame.setResizable(false); //设置窗口不能调整大小
        frame.setVisible(true); //将窗口显示出来
    }



    /** 该方法用于给每张卡牌添加点击事件 */
    public static void addClickAction(ArrayList<JButton> cards,JPanel panel){
        //再准备一个集合，存放下面卡槽中的卡牌
        ArrayList<JButton> belowCards = new ArrayList<>();
        for(int i=0;i<cards.size();i++){ //遍历所有卡牌
            JButton card = cards.get(i); //获取每一张卡牌
            card.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) { //点击卡牌时自动执行
                    if(belowCards.size()<7){ //卡槽中的卡牌不够7，则正常操作
                        JButton current = (JButton)e.getSource(); //获取被点击的卡牌
                        cards.remove(current); //1)将当前卡牌从cards中删除
                        int num = belowCards.size(); //想插入卡牌的下标位置(默认为追加)
                        for(int index=0;index<belowCards.size();index++){ //遍历卡槽的卡牌集合
                            JButton card = belowCards.get(index); //获取卡槽中的每张卡牌
                            if(current.getName().equals(card.getName())){ //若卡槽中有相同卡牌
                                num = index; //修改要插入卡牌的位置
                                break; //结束循环
                            }
                        }
                        belowCards.add(num,current); //2)将当前卡牌存入到belowCards卡槽集合中

                        /*
                          1)若num+2的值，小于卡槽集合的size()，才需要做3消的处理
                          2)若num位置后面的第2张卡牌的名字与当前所点击的卡牌名字相同，
                            说明3张卡牌连续了，则需要将它们从卡槽中删除
                         */
                        if(num+2<belowCards.size()){ //说明num后面最少有2张卡牌
                            JButton card = belowCards.get(num+2); //获取当前卡牌后面的第2张卡牌
                            //若当前卡牌与其后面的第2张卡牌的名字相同，说明三连了
                            if(current.getName().equals(card.getName())){ //说明三连了
                                //将下标num的元素从卡槽集合中删除，并返回被删除的卡牌存储到b1中
                                JButton b1 = belowCards.remove(num);
                                JButton b2 = belowCards.remove(num);
                                JButton b3 = belowCards.remove(num);
                                panel.remove(b1); //将b1从面板中删除
                                panel.remove(b2);
                                panel.remove(b3);
                                panel.updateUI(); //刷新面板，若不刷新则可能删掉的卡牌还在面板中显示(窗口自身问题)
                            }
                        }

                        for(int i=0;i<belowCards.size();i++){ //3)遍历卡槽中的所有卡牌
                            //+64而不是+59的原因: 仅仅是为了和槽子的格子对齐了好看
                            belowCards.get(i).setLocation(20+i*64,640); //设置卡槽中卡牌的位置
                        }
                        allCover(cards); //重新实现压牌
                        current.removeActionListener(current.getActionListeners()[0]); //删除卡牌点击事件(不要求掌握)
                    }else{ //够7了，则弹框提示游戏结束
                        JOptionPane.showMessageDialog(panel,"槽子已满，游戏结束"); // 弹出提示框(不要求掌握)
                    }
                }
            }); //给卡牌添加事件
        }
    }

    /** 该方法用于实现144张卡牌的压牌 */
    public static void allCover(ArrayList<JButton> cards){
        for(int index=0;index<cards.size();index++){ //遍历所有卡牌
            JButton bottom = cards.get(index); //获取下标index对应的卡牌作为bottom
            for(int i=index+1;i<cards.size();i++){ //遍历bottom后面的所有卡牌
                JButton top = cards.get(i); //获取后面的卡牌作为top
                boolean cov = isCovered(top,bottom); //判断是否压住
                if(cov){ //压住了
                    bottom.setEnabled(false); //设置卡牌按钮不可用
                    break; //结束循环，若不结束则后面的卡牌没压住时会走else又点亮了
                }else{ //没压住
                    bottom.setEnabled(true); //设置卡牌按钮可用
                    System.out.println(222);
                }
            }
        }
    }

    /** 该方法用于判断上面的卡牌top是否压住了下面的卡牌bottom */
    public static boolean isCovered(JButton top,JButton bottom){
        int x1 = bottom.getX()-59; //x1:bottom的x坐标-59
        int x2 = bottom.getX()+59; //x2:bottom的x坐标+59
        int y1 = bottom.getY()-60; //y1:bottom的y坐标-60
        int y2 = bottom.getY()+60; //y2:bottom的y坐标+60
        int x = top.getX(); //x:top的x坐标
        int y = top.getY(); //y:top的y坐标

        //x在x1与x2之间，并且，y在y1与y2之间，即为压住了
        return x>x1 && x<x2 && y>y1 && y<y2;
    }

    /*
      参数说明:
      1)ArrayList<JButton> cards:144张卡牌集合
      2)JPanel panel:面板
      3)int count:这一层共摆多少张卡牌
      4)int offset:这一层从集合的第几张卡牌开始摆
      5)int cols:这一层的一行有几张卡牌
      6)int x:这一层的第1张卡牌的x坐标
      7)int y:这一层的第1张卡牌的y坐标
     */
    /** 该方法用于摆放一层卡牌(发牌) */
    public static void putCards(ArrayList<JButton> cards,JPanel panel,int count,int offset,int cols,int x,int y){
        for(int i=0;i<count;i++){ //循环count次
            JButton card = cards.get(i+offset); //下标--从offset开始的count张卡牌
            card.setSize(59,66); //设置卡牌大小
            card.setLocation(x+i%cols*59,y+i/cols*60); //设置卡牌位置
            card.setBorderPainted(false); //设置不绘制按钮的边框
            card.setContentAreaFilled(false); //设置按钮内容区域不填充颜色
            panel.add(card,0); //将卡牌添加到面板上(0表示绘制在最上面)
        }
    }

    /** 该方法用于将144张卡牌存储到集合中 */
    public static ArrayList<JButton> createCards(){
        ArrayList<JButton> cards = new ArrayList<>(); //卡牌集合
        String[] names = {"刷子","剪刀","南瓜","奶瓶","干草",
                "手套","树桩","兔子","毛线","水桶",
                "树","苹果","白菜","草","萝卜","铃铛"}; //卡牌名称数组   //16*9  144
        for(int j=0;j<9;j++){ //循环9次---共9*16=144次
            for(int i=0;i<names.length;i++){ //遍历卡牌名称数组，循环走16次
                JButton card = new JButton(new ImageIcon("img/"+names[i]+".png")); //创建卡牌
                card.setDisabledIcon(new ImageIcon("img/"+names[i]+"2.png")); //设置不可用按钮图片
                card.setName(names[i]); //设置卡牌名称
                cards.add(card); //将卡牌card添加到cards集合中
            }
        }
        return cards; //返回卡牌集合
    }

    /** 该方法用于画背景图 */
    public static void paintBackground(JPanel panel){
        JLabel background = new JLabel(new ImageIcon("img/背景.jpg")); //图片标签
        background.setSize(480,800); //设置图片大小
        background.setLocation(0,0); //设置图片位置(0,0表示左上角)
        panel.add(background); //将图片标签添加到面板中
    }
}



